home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvhc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  8.5 KB  |  341 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVHC.CPP                             |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Power View Help Compiler             |
  8. // |                                                    |
  9. // |  Author:      Georgi Chalakov                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_malloc
  16. #define uses_stdio
  17. #define uses_stdlib
  18. #define uses_string
  19. #define uses_comlin
  20. #define uses_system
  21.  
  22. #include "PVuses.h"
  23.  
  24. #define TITLE      "\r\nPower View help file.\r\n\032"
  25. #define HELPIDX    "HELP_INDEX"
  26. #define BUFSIZE    16384
  27. #define MAXTOPICS   2000
  28. #define MAXREF       100
  29.  
  30. FILE *fi, *fo, *fh;
  31. unsigned char *bufin, *bufout;
  32. int    bufinp = 1;
  33. int    bufinl = 1;
  34. int    bufoutp = 0;
  35. long   putlen;
  36.  
  37.  
  38. struct token
  39. {
  40.   char *ident;
  41.   char *title;
  42.   int num;
  43. } tokens[MAXTOPICS];
  44.  
  45. struct item
  46. {
  47.   long offset;
  48.   int  size;
  49. } index[MAXTOPICS];
  50.  
  51. int tokenslen = 0;
  52.  
  53. void error( int flag, char *s, char *m )
  54. {
  55.   if( flag )
  56.   {
  57.     if( bufin!=NULL )
  58.       free( bufin );
  59.     if( bufout!=NULL )
  60.       free( bufout );
  61.     printf( "Error: %s %s\n", s, m );
  62.     exit( -1 );
  63.   }
  64. }
  65.  
  66. void flushout( void )
  67. {
  68.   fwrite( bufout, 1, bufoutp, fo );
  69. }
  70.  
  71. void _pch( int ch )
  72. {
  73.   putlen++;
  74.   if( bufoutp == BUFSIZE )
  75.   {
  76.     fwrite( bufout, 1, BUFSIZE, fo );
  77.     bufoutp = 0;
  78.   }
  79.   bufout[ bufoutp++ ] = ch;
  80. }
  81.  
  82. void pch( int ch )
  83. {
  84.   _pch( ch );
  85.   if( ch == '\r' ) _pch( ch );
  86. }
  87.  
  88. static int new_line;
  89.  
  90. int gch( void )
  91. {
  92.   static int ch = '\r';
  93.  
  94.   new_line = ( ch == '\r' ) || ( ch == '\n' );
  95.   if( !bufinl )
  96.   {
  97.     ch = '\r';
  98.     return -1;
  99.   }
  100.   if( bufinp == bufinl )
  101.   {
  102.     bufinp = 0;
  103.     bufinl = fread( bufin, 1, BUFSIZE, fi );
  104.   }
  105.   else
  106.   {
  107.     ch = bufin[bufinp++];
  108.     if( ch != '\n' ) return ch;
  109.   }
  110.   return gch();
  111. }
  112.  
  113. int tokencmp( const void *a, const void *b )
  114. {
  115.   return strcmp( ( ( struct token* )a )->title, ( ( struct token* )b )->title );
  116. }
  117.  
  118. void transfer( void )
  119. {
  120.   char stmp[256], *s;
  121.   int i, j, e;
  122.   int ch, tp, hif;
  123.   boolean dont_wrap = 0;
  124.  
  125.   memset( tokens, 0, sizeof( tokens ) );
  126.   printf( "Reading help topics...\n" );
  127.   fseek( fi, 0, 0 );
  128.   while( ( ch=gch() ) != -1 )
  129.   {
  130.     if( ch == '@' && new_line )
  131.     {
  132.       s = stmp;
  133.       while( ( ch = gch() ) != '\r' ) *s++ = ch;
  134.       *s = 0;
  135.       tokens[tokenslen].ident = strdup( stmp );
  136.       s = stmp;
  137.       while( ( ch = gch() ) != '\r' ) *s++ = ch;
  138.       *s = 0;
  139.       tokens[tokenslen].title = strdup( stmp );
  140.       for( i=0; ( i < tokenslen ) && strcmp( tokens[i].ident, stmp ); i++ );
  141.       error( i!=tokenslen, "Topic defined twice", tokens[i].ident );
  142.       tokens[tokenslen].num = tokenslen;
  143.       error( ++tokenslen==MAXTOPICS, "Too many topics found", "" );
  144.     }
  145.   }
  146.   printf( "Building help index...\n" );
  147.   fseek( fi, 0, 0 );
  148.   bufinp = bufinl = 1;
  149.   hif = tp = 0;
  150.   e = 2;
  151.   putlen = tokenslen*6 + sizeof( TITLE ) - 1;
  152.   fwrite( TITLE, 1, sizeof( TITLE ) - 1, fo );
  153.   fwrite( index, sizeof( struct item ), tokenslen, fo );
  154.   do
  155.   {
  156.     ch = gch();
  157.   proceed_char:
  158.     if( ch == -1 ) break;
  159.     switch( ch )
  160.     {
  161.       case '@':
  162.         if( new_line )
  163.         {
  164.           index[tp].offset = putlen;
  165.           while( gch()!='\r' );
  166.           while( gch()!='\r' );
  167.           e = 2;
  168.           if( !strcmp( tokens[tp].ident, HELPIDX ) ) hif++;
  169.         }
  170.         break;
  171.       case '`':
  172.         pch( '`' );
  173.         pch( '`' );
  174.         e = 2;
  175.         dont_wrap = 1;
  176.         break;
  177.       case '\r':
  178.         dont_wrap = 0;
  179.         e++;
  180.         if( e==2 )
  181.         {
  182.           pch( '\r' );
  183.           pch( '\r' );
  184.         }
  185.         else
  186.           if( e>2 )
  187.             pch( '\r' );
  188.           else
  189.           {
  190.             e = 1;
  191.             ch = gch();
  192.             if( ch != '\r' ) pch( ' ' );
  193.             goto proceed_char;
  194.           }
  195.         break;
  196.       case '~':
  197.         pch( '|' ); pch( 'b' );
  198.         for( i = 0; ( ( ch = gch() ) != '~' ) || ( i == MAXREF ); i++ )
  199.         {
  200.           if( ch == '\r' ) ch = ' ';
  201.           pch( ch );
  202.         }
  203.         error( i==MAXREF, "Reference too long", "" );
  204.         pch( '|' ); pch( 't' );
  205.         i = 0;
  206.         while( ( ( ch=gch() )!=' ' ) &&
  207.                ( ch != '\r' )        &&
  208.                ( ch != '.' )         &&
  209.                ( ch != ',' ) )
  210.           stmp[i++] = ch;
  211.         stmp[i] = 0;
  212.         for( i = 0; i < tokenslen; i++ )
  213.           if( !strcmp( tokens[i].ident, stmp ) )
  214.             break;
  215.         error( i==tokenslen, "Reference to undefined topic ", stmp );
  216.         i++;
  217.         _pch( i & 0xff );
  218.         _pch( i>>8 );
  219.         if( !dont_wrap ) e = 0;
  220.         goto proceed_char;
  221.       case '^':
  222.         if( new_line )
  223.         {
  224.           while( gch()!='\r' );
  225.           if( hif == 1 )
  226.           {
  227.             char letter = 0;
  228.             for( i = 0; i < tokenslen; i++ )
  229.               fprintf( fh, "#define ht%s %u\n", tokens[i].ident ,i+1 );
  230.             printf( "Sorting topics...\n" );
  231.             qsort( tokens, tokenslen, sizeof( struct token ), tokencmp );
  232.             hif++;
  233.             for( i = 0; i < tokenslen; i++ )
  234.             {
  235.               if( strcmp( tokens[i].ident, HELPIDX ) == 0 ) continue;
  236.               if( tokens[i].title[0] != letter )
  237.               {
  238.                 letter = tokens[i].title[0];
  239.                 pch( '\r' );
  240.                 pch( letter );
  241.                 pch( '\r' );
  242.               }
  243.               pch( '|' );
  244.               pch( 'b' );
  245.               for( j = 0; j < strlen( tokens[i].title ); j++ )
  246.                 pch( tokens[i].title[j] );
  247.               pch( '|' );
  248.               pch( 't' );
  249.               _pch( ( tokens[i].num+1 ) & 0xff );
  250.               _pch( ( tokens[i].num+1 ) >> 8 );
  251.               pch( '\r' );
  252.             }
  253.           }
  254.           index[tp++].size = ( int ) ( putlen - index[tp].offset );
  255.         }
  256.         break;
  257.       default:
  258.         if( !dont_wrap ) e = 0;
  259.         pch( ch );
  260.     }
  261.   }
  262.   while( 1 );
  263.   flushout();
  264.   fseek( fo, sizeof( TITLE ) - 1, 0 );
  265.   fwrite( index, sizeof( struct item ), tokenslen, fo );
  266. }
  267.  
  268.  
  269.  
  270. int main( int argc, char* argv[] )
  271. {
  272.   char input_fn[_MAX_PATH], output_fn[_MAX_PATH], header_fn[_MAX_PATH];
  273.  
  274.   bufin = (unsigned char *) malloc( BUFSIZE );
  275.   bufout = (unsigned char *) malloc( BUFSIZE );
  276.   error( bufout == NULL, "Not enought memory","" );
  277.  
  278.   __init_comlin( argc, argv );
  279.  
  280.   printf( "\
  281. Power View Help Compiler. Written by George Chalakov.\n\n"
  282.   );
  283.   if( param_opt( "/?" ) || ( argc == 1 ) )
  284.   {
  285.     printf( "\
  286. Syntax:\n\
  287.   PVHC <input_file[.TXT]> [<output_file>[.HLP]] [PVHT.H]\n\n\
  288. Description:\n\
  289.   This tool reads specified text file, produces a Power View Help file\n\
  290.   and exports help defines in a C-header file. The structure of input file is:\n\
  291. \n\
  292.   <topic_id>\n\
  293.   <index title>\n\
  294.   <text>\n\
  295.   <text>\n\
  296.   ...\n\
  297.   <end_of_topic>\n\
  298.   ...\n\
  299. \n\
  300.   <topic_id> ::= @<CPP_id>\n\
  301.   <index_title> - Cross-reference that appears in the Help Index\n\
  302.   <text> - single CRs are ignored, a ` marks line not to be wrapped.\n\
  303.            ~Cross reference~<CPP_id> means a hyper link.\n\
  304.   <end_of_topic> ::= ^\n"
  305.     );
  306.     exit( 0 );
  307.   }
  308.  
  309.   error( !param_filename( input_fn, ".TXT" ), "Missing input filename", "" );
  310.   if( !param_filename( output_fn, ".HLP" ) )
  311.   {
  312.     char _drive[_MAX_DRIVE];
  313.     char _dir[_MAX_DIR];
  314.     char _file[_MAX_FNAME];
  315.     char _ext[_MAX_EXT];
  316.  
  317.     _splitpath( input_fn, _drive, _dir, _file, _ext );
  318.     strcpy( _ext, ".HLP" );
  319.     _makepath( output_fn, _drive, _dir, _file, _ext );
  320.   }
  321.  
  322.   if( !param_filename( header_fn, ".H" ) )
  323.     strcpy( header_fn, "PVHT.H" );
  324.  
  325.   __tini_comlin();
  326.  
  327.   fi = fopen( input_fn, "rb" );
  328.     error( fi == NULL, "Can't open input file", input_fn );
  329.   fo = fopen( output_fn, "wb" );
  330.     error( fo == NULL, "Can't open output file", output_fn );
  331.   fh = fopen( header_fn, "wt" );
  332.     error( fh == NULL, "Can't open header file", header_fn );
  333.  
  334.   transfer();
  335.   fclose( fi );
  336.   fclose( fo );
  337.   fclose( fh );
  338.   printf( "Done.\n\nOutput file: %s\nHeader file: %s\n", fexpand( output_fn ), fexpand( header_fn ) );
  339.   return 0;
  340. }
  341.